﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CH.Easy.DbProvider.Common
{
    public static class DbProviderHelper
    {
        #region GetElementType
        public static Type GetElementType(Type seqType)
        {
            Type ienum = FindIEnumerable(seqType);
            if (ienum == null) return seqType;
            return ienum.GetGenericArguments()[0];
        }
        private static Type FindIEnumerable(Type seqType)
        {
            if (seqType == null || seqType == typeof(string))
                return null;
            if (seqType.IsArray)
                return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());
            if (seqType.IsGenericType)
            {
                foreach (Type arg in seqType.GetGenericArguments())
                {
                    Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
                    if (ienum.IsAssignableFrom(seqType))
                    {
                        return ienum;
                    }
                }
            }
            Type[] ifaces = seqType.GetInterfaces();
            if (ifaces != null && ifaces.Length > 0)
            {
                foreach (Type iface in ifaces)
                {
                    Type ienum = FindIEnumerable(iface);
                    if (ienum != null) return ienum;
                }
            }
            if (seqType.BaseType != null && seqType.BaseType != typeof(object))
            {
                return FindIEnumerable(seqType.BaseType);
            }
            return null;
        } 
        #endregion
        #region ChangeType
        public static object ChangeType(object value, Type type)
        {



            if (value is DBNull)
            {
                return typeof(DbProviderHelper).GetMethod("DefaultValue").MakeGenericMethod(type).Invoke(null, null);
            }






            if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
            if (value == null) return null;
            if (type == value.GetType()) return value;
            if (type.IsEnum)
            {
                if (value is string)
                    return Enum.Parse(type, value as string);
                else
                    return Enum.ToObject(type, value);
            }
            if (!type.IsInterface && type.IsGenericType)
            {
                Type innerType = type.GetGenericArguments()[0];
                object innerValue = ChangeType(value, innerType);
                return Activator.CreateInstance(type, new object[] { innerValue });
            }
            if (value is string && type == typeof(Guid)) return new Guid(value as string);
            if (value is string && type == typeof(Version)) return new Version(value as string);
            if (!(value is IConvertible)) return value;
            return Convert.ChangeType(value, type);
        }

        public static T GetFieldValue<T>(object value)
        {
            if (value is DBNull)
            {
                return (T)DefaultValue<T>();
            }

            return (T)value;
        }


        /// <summary>
        ///获取默认值
        /// </summary>
        /// <returns></returns>
        public static object DefaultValue<T>()
        {
            if (typeof(T) == typeof(string))
            {
                return string.Empty;
            }
            return default(T);
        }
        #endregion
    }
}
